\subsection{Эксплуатация строки формата}

Есть популярная ошибка, писать \TT{printf(string)} вместо \TT{puts(string)} или \TT{printf("\%s", string)}.
Если тот, кто пытается взломать систему удаленно, может указать свою \TT{string}, он/она может свалить процесс,
или даже получить доступ к переменным в локальном стеке.

Посмотрите на это:

\lstinputlisting[style=customc]{\CURPATH/f.c}

Нужно отметить, что у вызова \printf нет дополнительных аргументов кроме строки формата.

Теперь представим что это взломщик просунул строку \TT{\%s} как единственный аргумент последнего вызова \printf{}.
Я компилирую это в GCC 5.4.0 на x86 Ubuntu, и итоговый исполняемый файл печатает строку \q{world} при запуске!

Если я включаю оптимизацию, \printf выдает какой-то мусор, хотя, вероятно, вызовы strcpy() были оптимизированы,
и/или локальные переменные также.
Также, результат будет другой для x64-кода, другого компилятора, \ac{OS}, итд.

Теперь, скажем, взломщик может передать эту строку в вызов \printf{}: \TT{\%x \%x \%x \%x \%x}.
В моем случае, вывод это: \q{80485c6 b7751b48 1 0 80485c0} (это просто значения из локального стека).
Как видите, есть значение 1 и 0, и еще некоторые указатели (первый, наверное, указатель на строку \q{world}).
Так что если взломщик передаст строку \TT{\%s \%s \%s \%s \%s}, процесс упадет, потому что \printf считает 1 и/или 0
за указатель на строку, пытается читать символы оттуда, и терпит неудачу.

И даже хуже, в коде может быть \TT{sprintf (buf, string)}, где \TT{buf} это буфер в локальном стеке
с размером в 1024 байт или около того, взломщик может создать строку \TT{string} таким образом, что \TT{buf} будет
переполнен, может быть даже в таком виде, что это приведет к исполнению кода.

Многое популярное ПО было (или даже до сих пор) уязвимо:

\myindex{Quake}
\myindex{John Carmack}
\begin{framed}
\begin{quotation}
QuakeWorld went up, got to around 4000 users, then the master server exploded.

Disrupter and cohorts are working on more robust code now.

If anyone did it on purpose, how about letting us know... (It wasn't all the people that tried \%s as a name)
\end{quotation}
\end{framed}
( .plan-файл Джона Кармака, 17-декабрь-1996\footnote{\url{https://github.com/ESWAT/john-carmack-plan-archive/blob/33ae52fdba46aa0d1abfed6fc7598233748541c0/by_day/johnc_plan_19961217.txt}} )

В наше время, почти все современные компиляторы предупреждают об этом.

Еще одна проблема это менее известный аргумент \printf \TT{\%n}: когда \printf доходит до него в строке формата,
он пишет число выведенных символов в соответствующий аргумент:
\url{http://stackoverflow.com/questions/3401156/what-is-the-use-of-the-n-format-specifier-in-c}.
Так, взломщик может затереть локальные переменные перадавая в строке формата множество команд \TT{\%n}.

